"""
Copyright (c) 2023 - present SKbioinfo
"""

from flask_restful import reqparse,Resource
from flask import jsonify,request
from flask_login import login_required,current_user

from apps.NGS_API.project.db_project import *
from apps.NGS_API.record.interface_operate_his import parse_reason
from apps.NGS_API.utils.log_helper import lg
from apps.NGS_API.connector.db_common import *
from apps.NGS_API.common.db_table_config import *
from apps.NGS_API.common.common_generate_id import id_generator
from apps.NGS_API.record.history_util import *
pm = operation_monitor(table_name=ngs_op_log["name"])

'''
    Project infos.NGS_API 
'''
class interfaceProject(Resource):
    def __init__(self):
        self.gen = id_generator(name=project_db["name"])
    
    @login_required
    def get(self):
        try:
            mapping = {
                "proj_type":{
                    0:"自研项目",
                    1:"服务项目"
                }
            }
            projects = {}
            ### receive projects infos from database ###
            (project_total_number,project_base_info)=get_project_info()
            ### collect project_total number ###
            projects["project_total_number"] = project_total_number[0]
            ### collect project infos ###
            project_infos=[]
            ### rename project info columns ###
            for project in project_base_info:
                project_infos.append({
                    "id": project[11],
                    "proj_id": project[0],
                    "cli_id": project[1],
                    "prod_id": project[2],
                    "prot_id": project[3],
                    "sam_rec_id": project[4],
                    "proj_ty":mapping["proj_type"][project[5]],
                    "proj_le":project[6],
                    "cre_user":project[7],
                    "in_user":project[8],
                    "create_time":project[9],
                    "modify_time":project[10],
                    "status":project[12],
                    "proj_tag":project[13],
                    "pri_id":project[14],
                    "flag": False
                })
            ### update project status ###
            for i in range(0,len(project_infos)):
                if int(project_infos[i]["status"]) == 1:
                    project_infos[i].update({"status":"已完成"})
                elif int(project_infos[i]["status"]) == 0:
                    project_infos[i].update({"status":"进行中"})
            ### load project infos to project ###
            projects["project_infos"] = project_infos
            response=jsonify(projects)
            response.status_code = 202
            return response
        except Exception as e:
            lg.error(e)
    @login_required
    def post(self):
        parser=reqparse.RequestParser()
        parser.add_argument("primary_id",type=str,required=True,help="项目编号输入有误！")
        parser.add_argument("project_tag",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("client_id",type=str,required=True,help="客户编号输入有误！")
        parser.add_argument("product_id",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("protocol_id",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("sample_receive_id",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("project_type",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("project_level",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("create_user",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("incharge_user",type=str,required=True,help="项目名称输入有误！")
        parser.add_argument("status",type=str,required=True,help="项目状态输入有误！")
        args=parser.parse_args()
        ### project ID generator ###
        ids = self.gen.generate_id(col="project_id")
        project_id = int(ids["project_id"]) + 1
        project_prefix = self.gen.generate_prefix(tag="project")
        cols = '''
            project_id,
            primary_id,
            project_tag,
            client_id,
            product_id,
            protocol_id,
            sample_receive_id,
            project_type,
            project_level,
            create_user,
            incharge_user,
            create_time,
            modify_time,
            status       
        '''
        values = '''
            \"{project_id}\",
            \"{primary_id}\",
            \"{project_tag}\",
            \"{client_id}\",
            \"{product_id}\",
            \"{protocol_id}\",
            \"{sample_receive_id}\",
            {project_type},
            {project_level},
            \"{create_user}\",
            \"{incharge_user}\",
            \"{create_time}\",
            \"{modify_time}\",
            {status}
        '''.format(
            project_id = project_prefix + str(project_id),
            primary_id = args.get("primary_id"),
            project_tag = args.get("project_tag"),
            client_id = args.get("client_id"),
            product_id = args.get("product_id"),
            protocol_id = args.get("protocol_id"),
            sample_receive_id = args.get("sample_receive_id"),
            project_type = args.get("project_type"),
            project_level = args.get("project_level"),
            create_user = args.get("create_user"),
            incharge_user = args.get("incharge_user"),
            create_time = get_current_time(),
            modify_time = get_current_time(),
            status = args.get("status")
        )
        ### SQL: add project to database ###
        project_add_sql = '''
            INSERT INTO {table_name}
            ({cols}) VALUES ({values})
        '''.format(
            cols = cols,
            values = values,
            table_name = project_db["name"]
        )
        print(project_add_sql)
        add_info(project_add_sql)
        
class interfaceProjectID(Resource):
    ### CONTRUCTOR ###
    def __init__(self):
        self.sqlscript = create_msyql_sql(data_table=project_db)
    @login_required
    def delete(self,id):
        try:
            if request.data.decode(encoding='UTF-8',errors='strict') == "-1":
                pass
            else:
                ### SQL: record reason details ###
                reason_details = parse_reason(data=request.json)
                ### SQL: record user operation ###
                record_user_operate(
                    pm = pm,
                    current_user = current_user,
                    record_table = ngs_op_log["name"],
                    resource_table = project_db["name"],
                    ch_user = current_user,
                    type_name = "delete",
                    cols = '''
                        project_id
                    ''',
                    id = id,
                    reason_details = reason_details
                )
                ### SQL: delete project in database ###
                delete_sql = "DELETE FROM {table_name} WHERE {db_name} = \"{col_value}\"".format(
                    table_name=project_db["name"],
                    col_value=id,
                    db_name="id"
                )
                delete_info(delete_sql = delete_sql)
                return id
        except Exception as e:
            lg.error(e)

    @login_required
    def post(self,id):
        try:
            parser = reqparse.RequestParser()
            parser.add_argument("reason",type=str,help="",required=True)
            parser.add_argument("extra",type=str,help="",required=True)
            args=parser.parse_args()
            ### SQL: record reason details ###
            reason_details = parse_reason(data=args)
            ### SQL: record user operation ###
            record_user_operate(
                pm = pm,
                current_user = current_user,
                record_table = ngs_op_log["name"],
                resource_table = project_db["name"],
                ch_user = current_user,
                type_name = "delete",
                cols = '''
                    project_id
                ''',
                id = id,
                reason_details = reason_details
            )
            ### SQL: delete project in database ###
            delete_sql = "DELETE FROM {table_name} WHERE {db_name} =\"{col_value}\"".format(
                table_name=project_db["name"],
                db_name="id",
                col_value=id
            )
            delete_info(delete_sql=delete_sql)
        except Exception as e:
            lg.error(e)
            
    @login_required
    def put(self,id):
        try:
            parser = reqparse.RequestParser()
            parser.add_argument("proj_id",type=str,required=True,help="项目编号输入有误！")
            parser.add_argument("proj_tag",type=str,required=True,help="项目名称输入有误！")
            parser.add_argument("proj_le",type=int,required=True,help="项目等级输入有误！")
            parser.add_argument("proj_ty",type=int,required=True,help="项目类型输入有误！")
            parser.add_argument("cli_id",type=str,required=True,help="客户ID输入有误！")
            parser.add_argument("prod_id",type=str,required=True,help="产品编号输入有误！")
            parser.add_argument("prot_id",type=str,required=True,help="平台编号输入有误！")
            parser.add_argument("status",type=str,required=True,help="项目状态输入有误！")
            parser.add_argument("sam_rec_id",type=str,required=True,help="样品接收编号输入有误！")
            args=parser.parse_args()
            # ### record user operation ###
            record_user_operate(
                pm = pm,
                current_user = current_user,
                tag = "proj_id",
                record_table = ngs_op_log["name"],
                resource_table = project_db["name"],
                ch_user = current_user,
                type_name = "put",
                cols = project_db["match"],       
                id = id,
                later_infos = args,
                reason_details = ""
            )
            ### SQL: update project infos ###
            update_project_sql = '''
                UPDATE 
                    {table_name} 
                SET
                    project_id = \"{proj_id}\",
                    project_tag = \"{proj_tag}\",
                    project_level = {proj_le},
                    project_type = {proj_ty},
                    client_id = \"{cli_id}\",
                    product_id = \"{prod_id}\",
                    protocol_id = \"{prot_id}\",
                    status = {status}
                WHERE
                    project_id = \"{proj_id}\"
            '''.format(
                table_name = project_db["name"],
                proj_id = args.get("proj_id"),
                proj_tag = args.get("proj_tag"),
                proj_le = args.get("proj_le"),
                proj_ty = args.get("proj_ty"),
                cli_id = args.get("cli_id"),
                prod_id = args.get("prod_id"),
                prot_id = args.get("prot_id"),
                status = args.get("status")
            )
            ### SQL: update project infos ###
            update_info(update_project_sql)
        except Exception as e:
            lg.error(e)